package xunome.graphics;
/**
*
* @author Sem iNick
*/
import java.io.IOException;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.game.Sprite;
import xunome.game.BaseGame;
import xunome.game.Player;
import xunome.game.Card;
import xunome.game.Jogada;
import xunome.game.InvalidMove;
import xunome.game.multiplayerg.MultiPlayer;
public class GraphicUNO extends GameCanvas {
private BaseGame bgame;
private GraphicPlayer[] gPlayers;
private GraphicTable gTable;
private boolean showingxUno;
//private final int[] tablePos = {75, 75};
private final int TABLE_POSX;
private final int TABLE_POSY;
private final int DIRECTION_POSX;
private final int DIRECTION_POSY;
private final int ARROW_POSX;
private final int ARROW_POSY;
private boolean cheatActived = false;
private boolean cheating = false;
private String cheatBuffer = "";
private final String CHEAT = "1911";
public GraphicUNO(BaseGame game) {
super(false);
bgame = game;
this.setFullScreenMode(true);
//Draw players
Player[] players = bgame.getAllPlayers();
gPlayers = new GraphicPlayer[players.length];
int width = getWidth();
int height = getHeight();
if ((width < 220) && (height < 300)) {
TABLE_POSX = getWidth() / 2;
TABLE_POSY = 0;
DIRECTION_POSX = TABLE_POSX - 50;
DIRECTION_POSY = TABLE_POSY;
ARROW_POSX = DIRECTION_POSX + 40;
ARROW_POSY = 25;
} else {
TABLE_POSX = getWidth() / 2;
TABLE_POSY = 75;
DIRECTION_POSX = TABLE_POSX - 40;
DIRECTION_POSY = TABLE_POSY + 60;
ARROW_POSX = getWidth() / 2;
ARROW_POSY = 190;
}
for (int n = 0; n < players.length; n++) {
gPlayers[n] = new GraphicPlayer(players[n], width, height);
if (players[n].isLocalPlayer()) {
gPlayers[n].setShowFace(true);
}
}
//Create GraphicTable
gTable = new GraphicTable(bgame.getTable(), width, height);
}
public void refresh() {
Graphics g = getGraphics();
g.fillRect(0, 0, getWidth(), getHeight());
drawTable(g);
drawDirection(g);
drawArrowAtualPlayer(g);
//Refresh players
Player[] players = null;
if ((getWidth() < 220) && (getHeight() < 300)) {
players = new Player[1];
players[0] = bgame.getLocalPlayer();
//Draw number of cards for atual player in small screens
if (!bgame.getAtualPlayer().isLocalPlayer()) {
//Choose red color
g.setColor(255, 0, 0);
g.setFont(Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_BOLD, Font.SIZE_LARGE));
g.drawString(String.valueOf(bgame.getAtualPlayer().getNumberOfCards()),
DIRECTION_POSX + 10, DIRECTION_POSY + 35, 0); //Anchor 0 is default
}
} else {
players = bgame.getAllPlayers();
}
//Draw players
for(int n = 0; n < players.length; n++) {
gPlayers[n].repaint();
int anchor = Graphics.LEFT | Graphics.VCENTER;
if ((players[n].getPos() == GraphicPlayer.DOWN)
|| (players[n].getPos() == GraphicPlayer.UP)) {
anchor = Graphics.TOP | Graphics.HCENTER;
}
int[] pos = getPlayerPos(players[n].getPos());
g.drawImage(gPlayers[n].getRendered(), pos[0], pos[1], anchor);
}
paint(g);
flushGraphics();
}
public void drawTable(Graphics g) {
//Refresh table
gTable.repaint();
gTable.drawAtualColor(bgame.getAtualColorRGB());
g.drawImage(gTable.getRendered(), TABLE_POSX, TABLE_POSY,
Graphics.HCENTER | Graphics.TOP);
}
public void chooseColor() {
Graphics g = getGraphics();
try {
Image chooser = Image.createImage("/res/chooser.png");
g.drawImage(chooser, getWidth() / 2, getHeight() / 2,
Graphics.HCENTER | Graphics.VCENTER);
} catch (IOException io) {
//#ifdef DEBUG
System.out.println("Error when loading chooser image.");
//#endif
}
paint(g);
flushGraphics();
bgame.setChoose(true);
}
public void keyPressed(int keyP) {
if(keyP == GameCanvas.KEY_STAR) {
bgame.stopPlaying();
bgame = null;
gPlayers = null;
gTable = null;
return;
}
if(bgame.getChoose()) {
if(keyP == GameCanvas.KEY_NUM1) {
bgame.setColor(Card.BLUE);
bgame.setChoose(false);
} else if(keyP == GameCanvas.KEY_NUM3) {
bgame.setColor(Card.GREEN);
bgame.setChoose(false);
} else if(keyP == GameCanvas.KEY_NUM7) {
bgame.setColor(Card.RED);
bgame.setChoose(false);
} else if(keyP == GameCanvas.KEY_NUM9) {
bgame.setColor(Card.YELLOW);
bgame.setChoose(false);
}
/*if(!bgame.getChoose()) {
this.refresh();
}*/
return;
}
if(bgame.getAtualPlayer().getMasterPos() == bgame.getLocalPlayerPos()) {
Player p = bgame.getLocalPlayer();
//When player press '5', it tests if the player doesn't have a valid card.
if(keyP == GameCanvas.KEY_NUM5) {
if(p.checkHaveCard(bgame.getAtualColor(), bgame.getTable()
.getUpCard()) == Player.NONE) {
p.addCard(bgame.getTable().getCard(false));
this.refresh();
} else {
new Jogada(bgame);
addCheatBuffer(keyP);
return;
}
if(p.checkHaveCard(bgame.getAtualColor(), bgame.getTable()
.getUpCard()) == Player.NONE) {
if (bgame instanceof MultiPlayer) {
//#ifdef DEBUG
System.out.println("KEY5 Next");
//#endif
((MultiPlayer) bgame).nextPlayerRemote();
} else {
//#ifdef DEBUG
System.out.println("KEY Base");
//#endif
bgame.nextPlayer();
}
refresh();
}
return;
}
try {
if (keyP == KEY_NUM4) {
p.moveLeft();
refresh();
return;
} else if (keyP == KEY_NUM6) {
p.moveRight();
refresh();
return;
}
} catch (InvalidMove im) {}
}// End test if it's local player
if(bgame.getCallUno()) {
if(keyP == GameCanvas.KEY_NUM0) {
bgame.setCallUno(false);
drawCallUno();
return;
}
}
addCheatBuffer(keyP);
}//End keyPressed
public void pointerPressed(int x, int y) {
//Call UNO
if (bgame.getCallUno()) {
int xMin = 120;
int xMax = xMin + 30;
int yMin = 145;
int yMax = 145 + 30;
if (((x >= xMin) && (x <= xMax)) && ((y >= yMin) && (y <= yMax))) {
keyPressed(KEY_NUM0);
return;
}
}
//Choose Color
if (bgame.getChoose()) {
//Chooser equation (x - a)^2 + (y - b)^2 = r^2
//a = Circle's X, b = Circle's Y and r = radium
byte radium = 90;
int a = getWidth() / 2;
int b = getHeight() / 2;
int px = x - a;
int py = b - y;
//It tests if point is inside circle
int part1 = px * px;
int part2 = py * py;
if ((part1 + part2) <= (radium * radium)) {
//Firt quadrant
if ((px > 5) && (py > 5)) {
bgame.setColor(Card.GREEN);
bgame.setChoose(false);
} else if((px < 5) && (py > 5)) { //Second quadrant
bgame.setColor(Card.BLUE);
bgame.setChoose(false);
} else if ((px < 5) && (py < 5)) { //Third quadrant
bgame.setColor(Card.RED);
bgame.setChoose(false);
} else if ((px > 5) && (py < 5)) { //Fourth quadrant
bgame.setColor(Card.YELLOW);
bgame.setChoose(false);
}
}
return;
}
//Get card
int xMinGetCard = 75;
int yMinGetCard = 75;
int xMaxGetCard = xMinGetCard + 45;
int yMaxGetCard = yMinGetCard + 30;
if (((x >= xMinGetCard) && (x <= xMaxGetCard))
&& ((y >= yMinGetCard) && (y <= yMaxGetCard))) {
keyPressed(KEY_NUM5);
return;
}
//Select card
int yMax = getHeight();
int yMin = yMax - 68;
Player localPlayer = bgame.getLocalPlayer();
Player atualPlayer = bgame.getAtualPlayer();
int numberOfCards = localPlayer.getNumberOfCards();
int maxCards = numberOfCards;
if (numberOfCards > 15) {
maxCards = 15;
}
int xMin = (int)(120 - (maxCards + 1) / 2.0 * 15);
int xMax = xMin + (maxCards + 1) * 15;
if (((x <= xMax) && (x >= xMin)) && ((y <= yMax) && (y >= yMin))) {
boolean tryMove = false;
for (int atual = xMin; atual <= xMax; atual += 15) {
int atualCard = localPlayer.getAtualCardP();
int diff = 0;
if ((atualCard >= numberOfCards - 3) && (numberOfCards > 15)) {
diff = (numberOfCards - 15);
}
if (((atual - xMin) / 15 + diff) == (numberOfCards - 1)) {
if ((atual <= x) && (x <= (atual + 30))) {
//Verify if selected card is the card clicked
if (localPlayer.getAtualCardP() == numberOfCards -1) {
tryMove = (atualPlayer.isLocalPlayer());
} else {
//Just select the card
localPlayer.setAtual(numberOfCards - 1);
}
break;
}
} else if ((atual <= x) && (x <= (atual + 15))) {
int atualPos = (atual - xMin) / 15;
int selectCard = atualPos;
if (numberOfCards > 15) {
int mod = 0;
if (atualCard > 12) {
if (atualCard < numberOfCards - 2) {
mod = (atualCard - 12);
} else {
mod = numberOfCards - 15;
}
}
selectCard = atualPos + mod;
}
//Tests if selected card is the card clicked
if (localPlayer.getAtualCardP() == selectCard) {
tryMove = (atualPlayer.isLocalPlayer());
} else {
//Just select the card
localPlayer.setAtual(selectCard);
}
break;
}
}
if (tryMove) {
new Jogada(bgame);
}
refresh();
}
}
public void drawCallUno() {
Graphics g = getGraphics();
showingxUno = true;
try {
Image UNO = Image.createImage("/res/xuno.png");
g.drawImage(UNO, getWidth()/2, getHeight()/2, Graphics.HCENTER|Graphics.VCENTER);
paint(g);
flushGraphics();
Thread.sleep(3000);
} catch(IOException io) {
//#ifdef DEBUG
System.out.println("Error when loading xuno image.");
//#endif
} catch (InterruptedException t) {}
refresh();
showingxUno = false;
}
public void drawDirection(Graphics g) {
try {
Image direction = Image.createImage("/res/direction.png");
int directionTransform = (bgame.getDirection() == BaseGame.ANTICLOCKWISE)?
Sprite.TRANS_MIRROR:Sprite.TRANS_NONE;
g.drawRegion(direction, 0, 0, direction.getWidth(), direction.getHeight(),
directionTransform, DIRECTION_POSX, DIRECTION_POSY,
Graphics.TOP | Graphics.LEFT);
} catch (IOException io) {
//#ifdef DEBUG
System.out.println("Error when loading direction image file.");
//#endif
}
}
public void drawArrowAtualPlayer(Graphics g) {
try {
Image arrow = Image.createImage("/res/arrow.png");
int transformation = Sprite.TRANS_NONE;
switch (bgame.getAtualPlayer().getPos()) {
case GraphicPlayer.DOWN:
transformation = Sprite.TRANS_ROT180;
break;
case GraphicPlayer.LEFT:
transformation = Sprite.TRANS_ROT270;
break;
case GraphicPlayer.RIGHT:
transformation = Sprite.TRANS_ROT90;
break;
}
g.drawRegion(arrow, 0, 0, arrow.getWidth(), arrow.getHeight(),
transformation, ARROW_POSX, ARROW_POSY,
Graphics.TOP | Graphics.HCENTER);
} catch (IOException io) {
//#ifdef DEBUG
System.out.println("Errow when loading arrow image.");
//#endif
}
}
private int[] getPlayerPos(int position) {
int[] pos = new int[2]; //Index 0 represents cord x and index 1 cord y
switch (position) {
case GraphicPlayer.DOWN:
pos[0] = getWidth() / 2;
pos[1] = getHeight()-68;
break;
case GraphicPlayer.LEFT:
pos[0] = 5;
pos[1] = getHeight() / 2;
break;
case GraphicPlayer.UP:
pos[0] = getWidth() / 2;
pos[1] = 5;
break;
case GraphicPlayer.RIGHT:
pos[0] = getWidth() - 48;
pos[1] = getHeight() / 2;
break;
}
return pos;
}
public boolean isShowingXUNO() {
return showingxUno;
}
private void addCheatBuffer(int newKey) {
if ((newKey < KEY_NUM0) || (newKey > KEY_NUM9)) {
return;
}
if (!cheatActived) {
if (!cheating) {
cheating = true;
new Thread() {
public void run() {
try {
Thread.sleep((CHEAT.length() + 1) * 1000);
} catch (InterruptedException ie) {}
cheating = false;
cheatBuffer = "";
}
}.start();
}
int cheatLen = CHEAT.length();
cheatBuffer += (char) newKey;
int cheatBufferLen = cheatBuffer.length();
if (cheatBufferLen == cheatLen + 2) {
if (cheatBuffer.substring(0, cheatLen).equals(CHEAT)) {
try {
final int time = Integer.parseInt(cheatBuffer.charAt(cheatBufferLen - 2)
+ "");
final int type = Integer.parseInt(cheatBuffer.charAt(cheatBufferLen - 1)
+ "");
switch (type) {
case 1:
case 2:
case 3:
gPlayers[type].setShowFace(true);
cheatActived = true;
refresh();
new Thread() {
public void run() {
try {
Thread.sleep(time * 1000);
} catch (InterruptedException ie) {}
cheatActived = false;
gPlayers[type].setShowFace(false);
refresh();
}
}.start();
break;
case 5:
final int localPlayerPos = bgame.getLocalPlayerPos();
for (int p = 0; p < gPlayers.length; p++) {
if (p != localPlayerPos) {
gPlayers[p].setShowFace(true);
}
}
cheatActived = true;
refresh();
new Thread() {
public void run() {
try {
Thread.sleep(time * 1000);
} catch (InterruptedException ie) {}
for (int p = 0; p < gPlayers.length; p++) {
if (p != localPlayerPos) {
gPlayers[p].setShowFace(false);
}
}
cheatActived = false;
refresh();
}
}.start();
break;
}
} catch (Exception e) {}
}
cheatBuffer = "";
cheating = false;
}
}
}
}